<script>
import Item from './item.vue'

export default {
  name: 'ZVirtualList',
  props: {
    rootTag: {
      type: String,
      default: 'div'
    },
    bodyTag: {
      type: String,
      default: 'div'
    },
    dataSources: {
      type: Array,
      default: () => ([])
    },
    dataKey: {
      type: [String, Function],
      required: true
    },
    estimateSize: {
      type: Number,
      default: 50
    },
    keeps: {
      type: Number,
      default: 30
    },
    buffer: Number
  },
  data () {
    return {
      range: Object.create(null),
      sizes: new Map(),
      fixedSize: 0
    }
  },
  computed: {
    _buffer () {
      return this.buffer || Math.round(this.keeps / 3)
    },
  },
  methods: {
    onItemResized (key, size) {
      this.updateSize(key, size)
      this.$emit('resized', key, size)
    },
    onRootScroll (event) {
      const offsetSize = this.getOffsetSize()
      const clientSize = this.getClientSize()
      const scrollSize = this.getScrollSize()

      if (offsetSize < 0 || (offsetSize + clientSize > scrollSize + 1) || !scrollSize) {
        return
      }

    },
    getOffsetSize () {
      const el = this.$refs.root
      return el ? Math.ceil(el.scrollTop) : 0
    },
    getClientSize () {
      const el = this.$refs.root
      return el ? Math.ceil(el.clientHeight) : 0
    },
    getScrollSize () {
      const el = this.$refs.root
      return el ? Math.ceil(el.scrollHeight) : 0
    },
    updateSize (key, size) {
      this.sizes.set(key, size)
    }
  },
  created () {

  },
  render () {
    const { rootTag: RootTag, bodyTag: BodyTag, dataKey, onItemResized, onRootScroll } = this

    const { start = 0, end = this.keeps } = this.range

    const dataSources = this.dataSources.slice(start, end)

    return (
      <RootTag class="z-virtual-list" ref="root" onScroll={onRootScroll}>
        <BodyTag>
          {dataSources.map((item, index) => {
            const key = typeof dataKey === 'function' ? dataKey(item) : item[dataKey]

            return (
              <Item key={key} onResize={onItemResized}>
                {this.$scopedSlots.default ? this.$scopedSlots.default(item, index, key) : null}
              </Item>
            )
          })}
        </BodyTag>
      </RootTag>
    )
  }
}
</script>

<style lang="scss" scoped>
.z-virtual-list {
  height: 100%;
  overflow: auto;
}
</style>